package com.lightsh.things;

import org.jbox2d.common.Vec2;

import android.graphics.Color;
import android.graphics.Rect;
import android.view.MotionEvent;

import com.lightsh.body.PolygonImpl;
import com.lightsh.gui.PhysicsScreen;
import com.lightsh.joint.FastenRevoluteJoint;
import com.lightsh.utility.GeometryUtility;

public class Gun extends PolygonImpl{
	
	private static final String TAG = "Gun";
	
	protected int mBulletInterval = 20;
	protected int mIntervalCount = 0;
	
	private static final int GUN_WIDTH = 40;
	private static final int GUN_HEIGHT = 10;
	
	private static final int BULLET_RADIUS = 6;
	
	// joint的位置，即枪不会变的一个定点,px为单位
	private Vec2 mGunCenter; 
	private float mJointToMuzzleDistance;
	
	private float mTargetRadian = 0;
	
	private FastenRevoluteJoint mJoint;
	public Gun(PhysicsScreen screen, float x, float y, float density, float friction,
			float restitution) {
		super(screen, x, y, density, friction, restitution);
		add(new Vec2(0, 0), false);
		add(new Vec2(GUN_WIDTH, 0), false);
		add(new Vec2(GUN_WIDTH, GUN_HEIGHT), false);
		add(new Vec2(0, GUN_HEIGHT), true);
	}

	@Override
	public void update() {
		super.update();
		
		// 根据targetRadian转动
		checkJointRadian();
		
		checkInterval();
//		Debugger.logT(TAG, "joint = " + Utility.radianToAngle((float)(mJoint.getJoint().getJoint().getJointAngle() % (Math.PI * 2))));
//		Debugger.logT(TAG, "bodys = " + Utility.radianToAngle((float)(mBody.getAngle() % (Math.PI * 2))));
		
	}
	
	private void checkInterval(){
		if(++mIntervalCount >= mBulletInterval){
			generateBullet();
			mIntervalCount = 0;
		}
	}
	// 生成一个bullet
	private void generateBullet(){
		// 这里需要根据枪的长度和角度计算出子弹生成的位置
		Vec2 vec2 = getMuzzlePosition();
		BulletCircle circle = new BulletCircle(mParentScreen, vec2.x, vec2.y, BULLET_RADIUS, 0.1f, 1, 0.1f);
		circle.create();
		circle.setColor(Color.BLACK);
		
		// 添加的力度需要根据角度生成
		Vec2 forceVec2 = GeometryUtility.getTargetRadianPoint(0, 0, mBody.getAngle(), 5000);
		circle.applyForce(forceVec2);
	}

	@Override
	public void create() {
		super.create();		
		// 生成固定的joint
		final float scalle = 1f / 4f;
		mJointToMuzzleDistance = GUN_WIDTH * (1 - scalle);
		
		mGunCenter = new Vec2(mParentScreen.meterToPx(getPosition().x) + GUN_WIDTH * scalle, mParentScreen.meterToPx(getPosition().y) + GUN_HEIGHT / 2f);		
		
		Vec2 gunCenter = new Vec2(mParentScreen.pxToMeter(mGunCenter.x), mParentScreen.pxToMeter(mGunCenter.y));
		
		mJoint = new FastenRevoluteJoint(mWorld, getBody(), gunCenter);
		mJoint.create();		
//		mJoint.getJoint().setMotor(true, 10, 2);
//		joint.getJoint().setLimit(true, -90 * BaseBody.DEG_TO_RAD, 90 * BaseBody.DEG_TO_RAD);
		
//		Tester.testCircle(mGunCenter.x, mGunCenter.y, 50);
		
		// 添加自己到screen的动作响应列表中
		mParentScreen.addTouchListener(this);
	}
	
	private Vec2 getMuzzlePosition(){
		return GeometryUtility.getTargetRadianPoint(mGunCenter.x, mGunCenter.y, mBody.getAngle(), mJointToMuzzleDistance + BULLET_RADIUS + 4);
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev, float worldScale, float screenX, float screenY) {
		if(mParentScreen.isPause()){
			return false;
		}
		float targetX = ev.getX();
		float targetY = ev.getY();
		
		final float centerX = (mGunCenter.x - screenX) * worldScale;
		final float centerY = (mGunCenter.y - screenY) * worldScale;	
		
		
		if(GeometryUtility.getDistance(targetX, targetY, centerX, centerY) < 200){
			if(!(targetX == centerX && targetY == centerY)){
				mTargetRadian = GeometryUtility.getTargetRadian(centerX, centerY, targetX, targetY);
			}
			return true;
		}
//		Log.e(TAG, " target angle = " + Utility.radianToAngle(mTargetRadian));		
		return false;
	}
	private void checkJointRadian(){
		// 需要判断缩放		
		// joint的角度值与gun的角度值相反
		float jointRadian = -mJoint.getJoint().getJoint().getJointAngle();
		float targetRadian = mTargetRadian;
		
		// 需要将targetRadian转变为最接近jointRadian的值
		while(Math.abs(jointRadian - targetRadian) > Math.PI){
			targetRadian += (jointRadian > targetRadian ? 1 : -1) * 2 * Math.PI;
		}		
		if(!GeometryUtility.isEqual(targetRadian, jointRadian, 0.01f)){
//			Log.e(TAG, "jointRadian = " + jointRadian + ", targetRadian = " + targetRadian);
			float angleError = jointRadian - targetRadian;
			float gain = 10f;
			mJoint.getJoint().getJoint().setMotorSpeed(gain * angleError);
		}else{
			mJoint.getJoint().getJoint().setMotorSpeed(0);
		}
	}
	
	public void setTargetRadian(float targetRadian){
		mTargetRadian = targetRadian;
	}
	public void setGenerateBulletInterval(int interval){
		mBulletInterval = interval;
	}
}
